# Copyright 2014 Sean Burford <vk2ete@vk2ete.net>.  All Rights Reserved.
import datetime
import os
import re

import jinja2
import webapp2

import feed

JINJA_ENVIRONMENT = jinja2.Environment(
    loader=jinja2.FileSystemLoader(os.path.dirname(__file__) + '/html'),
    extensions=['jinja2.ext.autoescape'],
    autoescape=True)


def _ICalDate(date_time, timezone=None):
  if date_time.hour == 0 and date_time.minute == 0:
    year = date_time.strftime('%Y%m%d')
    return ';VALUE=DATE:%s' % (year,)
  else:
    time_str = date_time.strftime('%Y%m%dT%H%M00')
    if timezone and timezone != 'Australia/NSW':
      return ';TZID=/%s:%s' % (timezone, time_str)
    else:
      return ':%s' % (time_str,)


def _TextDate(date_start, date_end, timezone=None):
  dates = []
  dates.append(date_start.strftime('%b %e, %Y (%a)'))
  end = date_end.strftime('%b %e, %Y (%a)')
  if end not in dates:
    dates.append(end)
  return (' - '.join(dates)) or ''


def _TextTime(date_start, date_end, timezone=None):
  dates = []
  dates.append(date_start.strftime('%R'))
  end = date_end.strftime('%R')
  if date_start != date_end:
    dates.append(end)
  return (' - '.join(tm for tm in dates if tm != '00:00')) or ''


def _ICalString(text):
  # RFC5545 3.3.11 text escaping.
  if not text:
    return ''
  text = re.sub(r'([\,;])', r'\\\1', text)
  text = re.sub(r' & ', r' and ', text)
  return text


class ICalViewPage(webapp2.RequestHandler):

  def _Category(self, categories):
    return [self._feed_config.CategoryToText(cat) for cat in categories]

  def _RenderICalFeed(self, feed_config):
    self._feed_config = feed_config
    template_args = {}

    template_args['now_dt'] = datetime.datetime.now()

    if self.request.params.get('format') == 'ics':
      self.response.headers['Content-Type'] = 'text/calendar'
      filename = 'calendar.ics'
    elif self.request.params.get('format') == 'plain':
      filename = 'calendar.ics'
      self.response.headers['Content-Type'] = 'text/plain'
    else:
      self.response.headers['Content-Type'] = 'text/html'
      filename = 'calendar.html'

    query = {}
    for requested_category in self.request.params.getall('c'):
      for query_component in requested_category.upper().split(','):
        query.setdefault('category', set()).add(query_component.strip())
    template_args['categories'] = feed_config.feed_info.categories
    template_args['selected_categories'] = query.get('category', ())

    for requested_callsign in self.request.params.getall('s'):
      for query_component in requested_callsign.upper().split(','):
        query.setdefault('callsign', set()).add(query_component.strip())
    template_args['callsigns'] = ('VK0', 'VK1', 'VK2', 'VK3', 'VK4',
                                  'VK5', 'VK6', 'VK7', 'VK8', 'VK9')
    template_args['selected_callsigns'] = query.get('callsign', ())

    now = datetime.datetime.now()
    days = int(self.request.params.get('days', 90))
    date_range = (now - datetime.timedelta(days),
                  now + datetime.timedelta(days))
    template_args['events'] = feed_config.FetchEvents(date_range, query)

    template = JINJA_ENVIRONMENT.get_template(filename)
    self.response.write(template.render(template_args))

  def get(self):
    template_args = {}
    paths = self.request.path.split('/')
    feed_config = None

    JINJA_ENVIRONMENT.filters['category'] = self._Category
    JINJA_ENVIRONMENT.filters['icaldate'] = _ICalDate
    JINJA_ENVIRONMENT.filters['icalstr'] = _ICalString
    JINJA_ENVIRONMENT.filters['textdate'] = _TextDate
    JINJA_ENVIRONMENT.filters['texttime'] = _TextTime

    if len(paths) > 2:
      feed_name = paths[-1]

    if feed_name:
      try:
        feed_debug = (self.request.params.get('debug') == 'feed')
        feed_config = feed.Feed(feed_name, feed_debug)
      except (feed.Error, ValueError) as e:
        template_args['error'] = e
        try:
          self.response.status = e.status_code
        except AttributeError:
          pass

    if not feed_config:
      self.response.headers['Content-Type'] = 'text/html'
      template_args['title'] = 'Calendar Feeds'
      template_args['feeds'] = feed.Feed.GetFeedInfos()
      template = JINJA_ENVIRONMENT.get_template('feeds.html')
      self.response.write(template.render(template_args))
      return

    self._RenderICalFeed(feed_config)


application = webapp2.WSGIApplication([
    ('/.*', ICalViewPage),
], debug=False)

